import { _decorator, AudioClip, AudioSource, Component, Prefab, tween, UITransform, Node, Sprite } from 'cc';
import { Layer1 } from './Layer1';
import { Block } from './Block';
import { Layer2 } from './Layer2';
import { Layer3 } from './Layer3';
import { mainScene } from './mainScene';
import { EventDispatcher } from './EventDispatcher';
import { GameState } from './GameState';
const { ccclass, property } = _decorator;

@ccclass('LayerRoot')
export class LayerRoot extends Component {
    layer1:Layer1 = null;
    @property(Layer2)
    layer2:Layer2 = null;
    @property(Layer3)
    layer3:Layer3 = null;
    @property(Node)
    btnRedo:Node = null;
    @property(Node)
    btnRemove:Node = null;
    @property(Node)
    btnRandom:Node = null;
    @property([AudioClip])
    audios:AudioClip[] = [];

    private loadLayer1() {
        if(!this.layer1){
            this.layer1 = this.node.getChildByName('Layer1').getComponent(Layer1);
        }
    }
    protected start(): void {
        this.loadLayer1();
    }

    startGame(lv: number){
        this.loadLayer1();
        this.layer1.startGame(lv)
        EventDispatcher.getInstTarget().on(EventDispatcher.REVIVE_GAME, () => {
            this.clickRedo();
            this.clickRedo();
            this.clickRedo();
        }, this);
    }

    moveBlock(block: Block, blockPrefab: Prefab) {
        const newBlock = block.cloneBlock(this.node, blockPrefab);
        this.layer1.refreshShadow();
        if(this.layer3.getBlockSize() >= 7) return;
        const position = this.layer3.getBlockPosition(newBlock);
        const localPosition = this.node.getComponent(UITransform).convertToNodeSpaceAR(position);
        tween(newBlock.node).to(0.15, {
            position: localPosition
        }).call(() => {
            this.layer3.addBlock(newBlock);
            const hasSame = this.layer3.delSameBlocks();
            if(hasSame){
                this.playAudio(1);
                if(this.layer1.getBlockSize() === 0 &&
                    this.layer2.getBlockSize() === 0 && 
                    this.layer3.getBlockSize() === 0
                ){
                    this.node.parent.getComponent(mainScene).nextLevel();
                }
            }
            this.checkOver();
        }).start();
    }

    moveBlockBack(block: Block) {
        block.node.setParent(this.node);
        block.node.setPosition(this.node.getComponent(UITransform).convertToNodeSpaceAR(block.getTmpPosition()));
        if(this.layer3.getBlockSize() >= 7) return;
        const position = this.layer3.getBlockPosition(block);
        const localPosition = this.node.getComponent(UITransform).convertToNodeSpaceAR(position);
        tween(block.node).to(0.15, {
            position: localPosition
        }).call(() => {
            this.layer3.addBlock(block);
            const hasSame = this.layer3.delSameBlocks();
            if(hasSame){
                this.playAudio(1);
                if(this.layer1.getBlockSize() === 0 &&
                    this.layer2.getBlockSize() === 0 && 
                    this.layer3.getBlockSize() === 0
                ){
                    this.node.parent.getComponent(mainScene).nextLevel();
                }
            }
            this.checkOver();
        }).start();
    }
    checkOver() {
        if(this.layer3.getBlockSize() >= 7){
            EventDispatcher.getInstTarget().emit(EventDispatcher.GAME_OVER);
        }
    }
    playAudio(index: number) {
        this.getComponent(AudioSource).playOneShot(this.audios[index]);
    }

    clickRemove() {
        if(GameState.removeTimes <= 0){
            EventDispatcher.getInstTarget().emit(EventDispatcher.SHOW_TIPS, '没次数了')
            return;
        }
        if(this.layer3.getBlockSize() === 0) return;
        GameState.removeTimes -= 1;
        if(GameState.removeTimes <= 0){
            this.btnRemove.getComponent(Sprite).grayscale = true;
        }
        const temp = this.layer3.getRemoveBlocks();
        if(temp.length ==0) return;
        this.layer3.resetOrder();
        const layer2Zero = this.layer2.getZero();
        const local = this.node.getComponent(UITransform).convertToNodeSpaceAR(layer2Zero);
        for(let ele of temp){
            ele.node.setParent(this.node);
            ele.node.setPosition(this.node.getComponent(UITransform).convertToNodeSpaceAR(ele.getTmpPosition()));
            tween(ele.node).to(0.1, {
                position: local
            }).call(() => {
                this.layer2.addBlock(ele);
            }).start();
        }
    }

    clickRedo() {
        if(GameState.redoTimes <= 0){
            EventDispatcher.getInstTarget().emit(EventDispatcher.SHOW_TIPS, '没次数了')
            return;
        }
        if(this.layer3.getBlockSize() === 0) return;
        GameState.redoTimes -= 1;
        if(GameState.redoTimes <= 0){
            this.btnRedo.getComponent(Sprite).grayscale = true;
        }
        const temp = this.layer3.getLastBlock();
        if(!temp) return;
        const local = this.node.getComponent(UITransform).convertToNodeSpaceAR(temp.getTmpPosition());
        temp.node.setParent(this.node);
        temp.node.setPosition(local);
        const target = this.node.getComponent(UITransform).convertToNodeSpaceAR(temp.origin.node.getWorldPosition());
        tween(temp.node).to(0.1, {
            position: target
        }).call(() => {
            temp.origin.node.active = true;
            this.layer1.refreshShadow();
        }).removeSelf().start();

        this.layer3.resetOrder();
    }
}


